Return to Creative Coding Notebooks

Color of Noise



Overview and implementing of noise function focused on its power spectrum.

In [1]:
%matplotlib inline
import matplotlib.pyplot as plt
from IPython.display import Audio
import numpy as np

from _utils import *
In [2]:
fs = 44100                      # Sampling rate
dur = 10                        # Duration in seconds
t = np.linspace(0, dur, fs*dur) # Time vector

1. White noise


The power spectral density is equivalent to $\large \frac{1}{f^0}$, which is constant.

In [3]:
A = 0.5
X_white = np.random.uniform(-1, 1, fs*dur//2 + 1)
x_white = np.fft.irfft(X_white).real
x_white = A*x_white/np.abs(x_white).max()
x_white[-1] = 1 # fix normalized output
In [4]:
Audio(x_white, rate=fs)
Out[4]:
In [5]:
summary(x_white[:-1])
       min:         -0.5000
  1st Quar:         -0.0737
    median:         -0.0007
      mean:         -0.0003
  3rd Quar:          0.0732
       max:          0.4582
     sigma:          0.1091
In [6]:
audiovis(x_white[:-1], tlim=[0, 0.1])
audio mono
In [7]:
spectrogram(x_white, flim=[0, 20000])
audio mono
In [8]:
fig = plt.figure(figsize=(16, 8))

plt.psd(x_white, 2048, fs, color='#888888')

plt.xscale('log')
plt.xlim([1e2, 1e4])
plt.ylim([-80,-50])
plt.show()

2. Pink noise


The power spectral density is equivalent to $\large \frac{1}{f}$, which decreases 3 dB per octave.

In [9]:
A = 0.5
X_pink = np.random.uniform(-1, 1, fs*dur//2 + 1)
H = (np.arange(X_pink.size) + 1)**0.5
x_pink = np.fft.irfft(X_pink/H).real
x_pink = A*x_pink/np.abs(x_pink).max()
x_pink[-1] = 1 # fix normalized output
In [10]:
Audio(x_pink, rate=fs)
Out[10]:
In [11]:
summary(x_pink[:-1])
       min:         -0.5000
  1st Quar:         -0.0762
    median:         -0.0128
      mean:         -0.0123
  3rd Quar:          0.0508
       max:          0.4317
     sigma:          0.0962
In [12]:
audiovis(x_pink[:-1], tlim=[0, 0.1])
audio mono
In [13]:
spectrogram(x_pink, flim=[0, 20000])
audio mono
In [14]:
fig = plt.figure(figsize=(16, 8))

plt.psd(x_pink, 2048, fs, color='#FF88CC')

plt.xscale('log')
plt.xlim([1e2, 1e4])
plt.ylim([-80,-50])
plt.show()

3. Brown noise


The power spectral density is equivalent to $\large \frac{1}{f^2}$, which decreases 6 dB per octave.

In [15]:
A = 0.5
X_brown = np.random.uniform(-1, 1, fs*dur//2 + 1)
H = np.arange(X_brown.size) + 100
x_brown = np.fft.irfft(X_brown/H).real
x_brown = A*x_brown/np.abs(x_brown).max()
x_brown[-1] = 1 # fix normalized output
In [16]:
Audio(x_brown, rate=fs)
Out[16]:
In [17]:
summary(x_brown[:-1])
       min:         -0.5000
  1st Quar:         -0.1105
    median:         -0.0128
      mean:         -0.0102
  3rd Quar:          0.0852
       max:          0.4652
     sigma:          0.1420
In [18]:
audiovis(x_brown[:-1], tlim=[0, 0.1])
audio mono
In [19]:
spectrogram(x_brown, flim=[0, 20000])
audio mono
In [20]:
fig = plt.figure(figsize=(16, 8))

plt.psd(x_brown, 2048, fs, color='#AA4444')

plt.xscale('log')
plt.xlim([1e2, 1e4])
plt.ylim([-80,-50])
plt.show()

4. Blue noise


The power spectral density is equivalent to $\large f$, which increases 3 dB per octave.

In [21]:
A = 0.5
X_blue = np.random.uniform(-1, 1, fs*dur//2 + 1)
H = np.arange(X_blue.size)**0.5
x_blue = np.fft.irfft(X_blue*H).real
x_blue = A*x_blue/np.abs(x_blue).max()
x_blue[-1] = 1 # fix normalized output
In [22]:
Audio(x_blue, rate=fs)
Out[22]:
In [23]:
summary(x_blue[:-1])
       min:         -0.5000
  1st Quar:         -0.0733
    median:         -0.0000
      mean:         -0.0000
  3rd Quar:          0.0732
       max:          0.4736
     sigma:          0.1084
In [24]:
audiovis(x_blue[:-1], tlim=[0, 0.1])
audio mono
In [25]:
spectrogram(x_blue, flim=[0, 20000])
audio mono
In [26]:
fig = plt.figure(figsize=(16, 8))

plt.psd(x_blue, 2048, fs, color='#0088FF')

plt.xscale('log')
plt.xlim([1e2, 1e4])
plt.ylim([-90,-50])
plt.show()

5. Violet noise


The power spectral density is equivalent to $\large f^2$, which increases 6 dB per octave.

In [27]:
A = 0.5
X_violet = np.random.uniform(-1, 1, fs*dur//2 + 1)
H = np.arange(X_violet.size)
x_violet = np.fft.irfft(X_violet*H).real
x_violet = A*x_violet/np.abs(x_violet).max()
x_violet[-1] = 1 # fix normalized output
In [28]:
Audio(x_violet, rate=fs)
Out[28]:
In [29]:
summary(x_violet[:-1])
       min:         -0.5000
  1st Quar:         -0.0743
    median:          0.0002
      mean:          0.0000
  3rd Quar:          0.0746
       max:          0.4958
     sigma:          0.1104
In [30]:
audiovis(x_violet[:-1], tlim=[0, 0.1])
audio mono
In [31]:
spectrogram(x_violet, flim=[0, 20000])
audio mono
In [32]:
fig = plt.figure(figsize=(16, 8))

plt.psd(x_violet, 2048, fs, color='#AA00FF')

plt.xscale('log')
plt.xlim([1e2, 1e4])
plt.ylim([-90,-50])
plt.show()

6. The colours of noise


In [33]:
fig = plt.figure(figsize=(16, 8))

plt.psd(x_violet, 2048, fs, color='#AA00FF')
plt.psd(x_blue, 2048, fs, color='#0088FF')
plt.psd(x_white, 2048, fs, color='#888888')
plt.psd(x_pink, 2048, fs, color='#FF88CC')
plt.psd(x_brown, 2048, fs, color='#AA4444')

plt.xscale('log')
plt.xlim([1e2, 1e4])
plt.ylim([-90,-50])
plt.show()